/*  
    Copyright 2010 Mike Eheler <mike.eheler@gmail.com>

    This file is part of Four Falling Blocks Puzzle Game.

    Four Falling Blocks Puzzle Game is free software: you can
	redistribute it and/or modify it under the terms of the GNU General
	Public License as published by the Free Software Foundation, either
	version 3 of the License, or (at your option) any later version.

    Four Falling Blocks Puzzle Game is distributed in the hope that it
	will be useful, but WITHOUT ANY WARRANTY; without even the implied
	warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Four Falling Blocks Puzzle Game.
	
	If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "types.h"

class Piece;

class Board
{
public:
	Board();
	Board( Board const & );
	~Board();

	Board & operator=( Board const & );
	bool    operator==( Board const & );

	int8_t const * board() const;

	void clear();

	void clearRow( uint8_t row );
	void clearRows( uint8_t & cleared, uint8_t & consecutive );

	bool inBounds( int8_t row, int8_t col ) const;
	bool pieceInBounds( uint8_t const *, int8_t row, int8_t col ) const;
	bool pieceInBounds( Piece *, int8_t row, int8_t col ) const;
	bool pieceCollides( uint8_t const *, int8_t row, int8_t col ) const;
	bool pieceCollides( Piece *, int8_t row, int8_t col ) const;

	int8_t at( int8_t row, int8_t col ) const;
	void placePiece( Piece *, int8_t row, int8_t col );

private:
	int8_t mBoard[20][10];
};

// INLINE //

inline Board & Board::operator=( Board const & that )
{
	memcpy( mBoard, that.mBoard, sizeof(int8_t) * 200 );
	return *this;
}

inline bool Board::operator==( Board const & that )
{
	for( size_t y = 0; y < 20; y++ )
		for( size_t x = 0; x < 10; x++ )
			if( mBoard[y][x] != that.mBoard[y][x] )
				return false;

	return true;
}

inline int8_t const * Board::board() const
{
	return &mBoard[0][0];
}

inline bool Board::inBounds( int8_t row, int8_t col ) const
{
	return row >= 0 && row < 20 && col >= 0 && col < 10;
}

inline int8_t Board::at( int8_t row, int8_t col ) const
{
	if( inBounds(row,col) )
		return mBoard[row][col];

	return -1;
}
